package com.chenjt.juc.three_completableFuture;

import java.util.concurrent.*;

/**
 * 注释：
 *
 * @author chenjt
 * @date 2024/7/6 10:02
 */
public class CompletableFutureUserDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

//        completableFutureSupportFutureTask();

        // 要用自定义线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        try {
            CompletableFuture.supplyAsync(() -> {
                System.out.println(Thread.currentThread().getName() + "----come in");
                int result = ThreadLocalRandom.current().nextInt(10);

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("1秒后出结果" + result);

                // 模拟异常情况，让他进入exceptionally中
                if(result>5){
                    int i = 1/0;
                }

                return result;
            },threadPool).whenComplete((v,e)->{
                //e是异常，v是上面运行完成的result
                if(e == null){
                    System.out.println("计算完成，更行系统UpdateValue:" + v);
                }
            }).exceptionally(e->{
                e.printStackTrace();
                System.out.println("异常情况：" + e.getCause() + "\t" + e.getMessage());
                return null;
            });
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }

        System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");

        // 这里不加的话，主线程运行太快，不会等次线程，会直接关闭，不会输出次线程的结果
        // 不用自定义线程池的话，主线程不要立刻结束，否则completableFuture默认使用的线程池会立刻关闭
//        TimeUnit.SECONDS.sleep(3);


    }


    /**
     * futureTask能做的，CompletableFuture也能做
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void completableFutureSupportFutureTask() throws ExecutionException, InterruptedException{
        /**
         * 输出结果:
         * main线程先去忙其他任务
         * ForkJoinPool.commonPool-worker-1----come in
         * 1秒后出结果8
         * 8
         */
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "----come in");
            int result = ThreadLocalRandom.current().nextInt(10);

            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("1秒后出结果" + result);
            return result;
        });

        System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");

        System.out.println(completableFuture.get());
    }

}
